package org.dftproject.genesis.ui.pages.summary.details;

import java.util.HashSet;
import java.util.Set;

import org.dftproject.genesis.data.IAttribute;
import org.dftproject.genesis.data.genealogy.GenealogyConstants;
import org.dftproject.genesis.data.genealogy.IEvent;
import org.dftproject.genesis.data.genealogy.IInstant;
import org.dftproject.genesis.data.genealogy.IPerson;
import org.dftproject.genesis.data.genealogy.IPlace;
import org.dftproject.genesis.data.genealogy.IRole;
import org.dftproject.genesis.ui.figures.IHyperlinkListener;
import org.dftproject.genesis.ui.pages.PageManager;
import org.dftproject.genesis.ui.pages.place.PlacePage;
import org.dftproject.genesis.ui.pages.place.PlacePageInput;
import org.dftproject.genesis.ui.pages.summary.SummaryPage;
import org.dftproject.genesis.ui.pages.summary.SummaryPageInput;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

public class ParentFigure extends Figure {
	
	private final FigureListViewer viewer;
	
	public ParentFigure(final IPerson parent, final IPerson spouse) {
		ToolbarLayout layout = new ToolbarLayout(false);
		layout.setSpacing(2);
		setLayoutManager(layout);
		
		PersonHyperlinkFigure personFigure = new PersonHyperlinkFigure(parent);
		personFigure.addHyperlinkListener(new IHyperlinkListener() {

			public void linkActivated(Object data, int stateMask) {
				if (data instanceof IPerson) {
					IWorkbench workbench = PlatformUI.getWorkbench();
					IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
					IWorkbenchPage workbenchPage = window.getActivePage();
					PageManager.getDefault().openPage(workbenchPage, new SummaryPageInput((IPerson) data), SummaryPage.ID, true, (stateMask & SWT.CTRL) != 0);
				}
			}
			
		});
		add(personFigure);
		
		IFigure eventFigure = new Figure();
		layout = new ToolbarLayout(false);
		layout.setSpacing(2);
		eventFigure.setBorder(new MarginBorder(0, 20, 0, 0));
		eventFigure.setLayoutManager(layout);
		add(eventFigure);
		
		viewer = new FigureListViewer(eventFigure);
		viewer.setContentProvider(new IStructuredContentProvider() {

			public Object[] getElements(Object input) {
				return new Object[0];
			}
			
			public void dispose() {
			}

			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			}

		});
		viewer.setFigureProvider(new IFigureProvider() {

			public IFigure getFigure(Object element) {
				if (element instanceof IAttribute) {
					IAttribute attribute = (IAttribute) element;
					Object value = attribute.getValue();
					if (value instanceof IInstant) {
						return new DateFigure((IInstant) value);
					} else if (value instanceof IPlace) {
						IPlace place = (IPlace) value;
						PlaceHyperlinkFigure figure = new PlaceHyperlinkFigure(place);
						figure.addHyperlinkListener(new IHyperlinkListener() {

							public void linkActivated(Object data, int stateMask) {
								if (data instanceof IPlace) {
									IWorkbench workbench = PlatformUI.getWorkbench();
									IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
									IWorkbenchPage workbenchPage = window.getActivePage();
									PageManager.getDefault().openPage(workbenchPage, new PlacePageInput((IPlace) data), PlacePage.ID, true, (stateMask & SWT.CTRL) != 0);
								}
							}
							
						});
						return figure;
					}
				}
				return null;
			}

		});
		viewer.setComparator(new ViewerComparator() {

			@Override
			public int compare(Viewer viewer, Object o1, Object o2) {
				if (o1 instanceof IAttribute)
					o1 = ((IAttribute) o1).getValue();
				if (o2 instanceof IAttribute)
					o2 = ((IAttribute) o2).getValue();
				
				if (o1 instanceof IInstant) 
					return -1;
				if (o2 instanceof IInstant) 
					return 1;
				if (o1 instanceof IPlace) 
					return -1;
				if (o2 instanceof IPlace) 
					return 1;
				return o1.hashCode() - o2.hashCode();
			}

		});
		viewer.setInput(this);
		
		Job job = new Job("Populate event") {

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				final Set<Object> elements = new HashSet<Object>();
				
				for (IRole role : parent.getRoles(GenealogyConstants.Spouse)) {
					IEvent event = role.getEvent();
					for (IRole otherRole : event.getRoles(GenealogyConstants.Spouse)) {
						if (spouse.sameAs(otherRole.getPerson())) {
							elements.addAll(event.getAttributes());
							break;
						}
					}
				}
				
				Display.getDefault().asyncExec(new Runnable() {

					public void run() {
						viewer.add(elements.toArray());
					}
					
				});
				
				return Status.OK_STATUS;
			}
			
		};
		job.schedule();
	}

	private final Color gradientBottom = new Color(null, 196, 225, 255);
	private final Color gradientTop = new Color(null, 234, 244, 255);
	
	@Override
	public void paintFigure(Graphics graphics) {
		graphics.pushState();		
		graphics.setForegroundColor(gradientTop);
		graphics.setBackgroundColor(gradientBottom);
		graphics.fillGradient(getBounds(), true);
		graphics.popState();
		
		super.paintFigure(graphics);
	}
	
	protected String getLabel(IRole role) {
		if (GenealogyConstants.Spouse.equals(role.getType()))
			return "Marriage:";
		return "Unknown:";
	}

}
